package org.lex.dbq.model.jdbc.template.parser;

import java.util.ArrayList;
import java.util.List;

import org.lex.dbq.model.bo.Variable;
import org.lex.dbq.model.jdbc.template.IJdbcUrlContext;
import org.lex.string.StringUtils;

public class OptionalFragment extends Fragment {
	private List<Fragment> children = new ArrayList<Fragment>();

	/**
	 * 
	 * @param image
	 *            like "</${database}>"
	 */
	public OptionalFragment(String image) {
		super(image);
		normalize(this);
	}

	void addFragment(Fragment f) {
		children.add(f);
	}

	public List<Fragment> getChildren() {
		return children;
	}

	private void normalize(OptionalFragment f) {
		String image = f.getImage().trim();
		String src = image.substring(1, image.length() - 1);
		FragmentLexer lexer = new FragmentLexer(src);
		while (true) {
			Fragment child = lexer.getNext();
			if (null == child) {
				break;
			} else {
				f.addFragment(child);
			}
		}
	}

	@Override
	public String evaluate(IJdbcUrlContext context) {
		boolean visible = true;
		StringBuilder buf = new StringBuilder();
		for (Fragment f : children) {
			if (f instanceof VariableFragment) {
				VariableFragment vf = (VariableFragment) f;
				String varName = vf.getVariableName();
				Variable var = context.getVariable(varName);
				String varValue = context.getVariableValue(var);
				if (StringUtils.isNullOrTrimEmpty(varValue)) {
					varValue = var.getDefaultValue();
				}
				if (StringUtils.isNullOrTrimEmpty(varValue)) {
					visible = false;
				}
			}
			buf.append(f.evaluate(context));
		}
		String value = "";
		if (true == visible) {
			value = buf.toString();
		}
		return value;
	}

	public String toString() {
		return toString("  ");
	}

	private String toString(String ident) {
		StringBuilder buf = new StringBuilder();
		buf.append("====Begin OptionalFragment[");
		buf.append(getImage());
		buf.append("]#").append(children.size());
		buf.append("====\n");
		for (Fragment f : children) {
			buf.append(ident);
			buf.append(ident);
			if (f instanceof OptionalFragment) {
				buf.append(((OptionalFragment) f).toString(ident + "  "));
			} else {
				buf.append(f).append('\n');
			}
		}
		return buf.toString();
	}
}
